#!pip install tensorflow
import tensorflow as tf
from tensorflow.keras import models, layers
import matplotlib.pyplot as plt
imageSize = 256 # Setting the image size as that of properties
batchSize = 32 # Making a group of 32 images
channels = 3 # RGB values
epochs = 10 #
#Potato plant
potato_dataset = tf.keras.preprocessing.image_dataset_from_directory(
"PotatoPlant",
shuffle=True,
image_size = (imageSize,imageSize),
batch_size = batchSize
)
Found 2152 files belonging to 3 classes.
class_names = potato_dataset.class_names
class_names #Names of folder present in PotatoPlant
['Potato___Early_blight', 'Potato___Late_blight', 'Potato___healthy']
len(potato_dataset)
68
68*32 #length of dataset and batch size
2176
for image_batch, label_batch in potato_dataset.take(1):
print(image_batch.shape)
print(label_batch.numpy())
#Basically it provides a batch size, image size and RGB channels
#label batch signifies the class number
(32, 256, 256, 3) [1 1 1 0 1 1 0 0 0 1 0 1 1 0 0 0 1 0 0 2 0 0 1 2 0 1 1 1 0 1 1 0]
plt.figure(figsize=(10, 10))
for image_batch, label_batch in potato_dataset.take(1):
for i in range(16): #here in range max value we can give is 32 bcoz batch size is 32
ax = plt.subplot(4, 4, i + 1)
plt.imshow(image_batch[i].numpy().astype("uint8"))
plt.title(class_names[label_batch[i]])
plt.axis("off")
len(potato_dataset)
68
# 70% -> Training dataset
# 15% -> Validation dataset
# 15% -> Testing dataset
train_size = 0.7
len(potato_dataset)*train_size
47.599999999999994
train_potatodataset = potato_dataset.take(47) # Considering first 47 values
len(train_potatodataset)
47
test_potatodataset = potato_dataset.skip(47) # Considering values after 47
len(test_potatodataset)
21
validation_size = 0.15
len(potato_dataset)*validation_size
10.2
validation_potatodataset = test_potatodataset.take(10)
len(validation_potatodataset)
10
test_potatodataset = test_potatodataset.skip(10)
len(test_potatodataset)
11
def get_dataset_partitions_tf(ds, train_split = 0.7, val_split = 0.15, test_split = 0.15, shuffle=True, shuffle_size=10000):
if shuffle:
ds = ds.shuffle(shuffle_size, seed = 15)
ds_size = len(ds)
train_size = int(train_split*ds_size)
val_size = int(val_split*ds_size)
test_size = int(test_split*ds_size)
train_ds = ds.take(train_size)
validation_ds = ds.skip(train_size).take(val_size)
test_ds = ds.skip(train_size).skip(val_size)
return train_ds, validation_ds, test_ds
train_ds, validation_ds, test_ds = get_dataset_partitions_tf(potato_dataset)
print(len(train_ds))
print(len(validation_ds))
print(len(test_ds))
47 10 11
# Here cache is used to store the image so that we can read the image from the disk which improves the performance.
# Prefetch is used because if GPU is busy with training purpose meanwhile CPU will read the next batch so that the performance is optimized.
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
validation_ds = validation_ds.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
test_ds = test_ds.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
#Thus we get the optimized Training, Validation and Testing dataset.
#Data preprocessing
resize_and_rescale = tf.keras.Sequential([
layers.experimental.preprocessing.Resizing(imageSize, imageSize), #Suppose if the size of image is not 256 then this will take care of that.
layers.experimental.preprocessing.Rescaling(1.0/255) #Rescaling the image to 255 and supply the layer when we actually build our model.
])
#Data augmentation :- Techniques used to increase the amount of data by adding slightly modified copies of already existing data
data_augmentation = tf.keras.Sequential([
layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical"),
layers.experimental.preprocessing.RandomRotation(0.2)
])
#We just created layers for preprocessing and we will this layer in our actual model.
input_shape = (batchSize, imageSize, imageSize, channels)
n_classes = 3
model = models.Sequential([
resize_and_rescale,
layers.Conv2D(32, kernel_size = (3,3), activation='relu', input_shape=input_shape),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(n_classes, activation='softmax'), #softmax function -> normalize the probability of your classes.
])
model.build(input_shape=input_shape)
model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
sequential (Sequential) (32, 256, 256, 3) 0
conv2d (Conv2D) (32, 254, 254, 32) 896
max_pooling2d (MaxPooling2D (32, 127, 127, 32) 0
)
conv2d_1 (Conv2D) (32, 125, 125, 64) 18496
max_pooling2d_1 (MaxPooling (32, 62, 62, 64) 0
2D)
conv2d_2 (Conv2D) (32, 60, 60, 64) 36928
max_pooling2d_2 (MaxPooling (32, 30, 30, 64) 0
2D)
conv2d_3 (Conv2D) (32, 28, 28, 64) 36928
max_pooling2d_3 (MaxPooling (32, 14, 14, 64) 0
2D)
conv2d_4 (Conv2D) (32, 12, 12, 64) 36928
max_pooling2d_4 (MaxPooling (32, 6, 6, 64) 0
2D)
conv2d_5 (Conv2D) (32, 4, 4, 64) 36928
max_pooling2d_5 (MaxPooling (32, 2, 2, 64) 0
2D)
flatten (Flatten) (32, 256) 0
dense (Dense) (32, 64) 16448
dense_1 (Dense) (32, 3) 195
=================================================================
Total params: 183,747
Trainable params: 183,747
Non-trainable params: 0
_________________________________________________________________
model.compile(
optimizer = 'adam',
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits = False),
metrics = ['accuracy'] #to track the gradient descent/ training process.
)
epochs = 10
results = model.fit(
train_ds,
batch_size=batchSize,
validation_data=validation_ds,
verbose=1,
epochs=epochs,
)
Epoch 1/10 47/47 [==============================] - 55s 1s/step - loss: 0.8916 - accuracy: 0.5264 - val_loss: 0.7920 - val_accuracy: 0.6375 Epoch 2/10 47/47 [==============================] - 58s 1s/step - loss: 0.6598 - accuracy: 0.7081 - val_loss: 0.4373 - val_accuracy: 0.8031 Epoch 3/10 47/47 [==============================] - 59s 1s/step - loss: 0.3786 - accuracy: 0.8372 - val_loss: 0.2665 - val_accuracy: 0.8750 Epoch 4/10 47/47 [==============================] - 57s 1s/step - loss: 0.3530 - accuracy: 0.8635 - val_loss: 0.2546 - val_accuracy: 0.8938 Epoch 5/10 47/47 [==============================] - 56s 1s/step - loss: 0.2875 - accuracy: 0.8851 - val_loss: 0.1862 - val_accuracy: 0.9312 Epoch 6/10 47/47 [==============================] - 55s 1s/step - loss: 0.2321 - accuracy: 0.9095 - val_loss: 0.1880 - val_accuracy: 0.9187 Epoch 7/10 47/47 [==============================] - 54s 1s/step - loss: 0.2386 - accuracy: 0.9027 - val_loss: 0.1518 - val_accuracy: 0.9375 Epoch 8/10 47/47 [==============================] - 54s 1s/step - loss: 0.1902 - accuracy: 0.9216 - val_loss: 0.2473 - val_accuracy: 0.9094 Epoch 9/10 47/47 [==============================] - 54s 1s/step - loss: 0.1596 - accuracy: 0.9419 - val_loss: 0.1149 - val_accuracy: 0.9563 Epoch 10/10 47/47 [==============================] - 54s 1s/step - loss: 0.1382 - accuracy: 0.9446 - val_loss: 0.0879 - val_accuracy: 0.9656
scores = model.evaluate(test_ds) #Testing accuracy
11/11 [==============================] - 3s 218ms/step - loss: 0.1211 - accuracy: 0.9460
scores #returns loss and accuracy
[0.1210547462105751, 0.9460227489471436]
results #history
<keras.callbacks.History at 0x2037d806790>
results.params
{'verbose': 1, 'epochs': 10, 'steps': 47}
results.history.keys()
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
accuracy = results.history['accuracy']
val_accuracy = results.history['val_accuracy']
loss = results.history['loss']
val_loss = results.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(range(epochs), accuracy, label='Training Accuracy')
plt.plot(range(epochs), val_accuracy, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(range(epochs), loss, label='Training Loss')
plt.plot(range(epochs), val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
import numpy as np
for images_batch, labels_batch in test_ds.take(1): # where 1 is the number of batches
#print(images_batch[0]) #Tensor format
#print(images_batch[0].numpy()) #Numpy format
#plt.imshow(images_batch[0].numpy().astype('uint8')) #Displays the actual image
first_image = images_batch[0].numpy().astype('uint8')
first_label = labels_batch[0].numpy()
print("Predicting the first image")
plt.imshow(first_image)
print("Actual class label:",class_names[first_label])
batch_prediction = model.predict(images_batch)
print("Predicted class label:",class_names[np.argmax(batch_prediction[0])])
Predicting the first image Actual class label: Potato___Early_blight Predicted class label: Potato___Early_blight
#Creating a function for inference
def predict_model(model, img):
img_array = tf.keras.preprocessing.image.img_to_array(images[i].numpy())
img_array = tf.expand_dims(img_array, 0)
predictions = model.predict(img_array)
predicted_class = class_names[np.argmax(predictions[0])]
confidence = round(100 * (np.max(predictions[0])), 2)
return predicted_class, confidence
#Running the inference on few sample images
plt.figure(figsize=(15, 15))
for images, labels in test_ds.take(1): #Taking 1 batch
for i in range(9): #Considering 9 images at a time
ax = plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
predicted_class, confidence = predict_model(model, images[i].numpy())
actual_class = class_names[labels[i]]
plt.title(f"Actual class label: {actual_class},\n Predicted class label: {predicted_class}.\n Confidence: {confidence}%")
plt.axis("off") #Removing the axes
import os
model_version=max([int(i) for i in os.listdir("saved_models/") + [0]])+1
model.save(f"./saved_models/{model_version}")
INFO:tensorflow:Assets written to: ./saved_models/2\assets
#imageSize = 256
#batchSize = 32
#channels = 3
#epochs = 50
#BellPepper plant
bellpepper_dataset = tf.keras.preprocessing.image_dataset_from_directory(
"BellPepperPlant",
shuffle=True,
image_size = (imageSize,imageSize),
batch_size = batchSize
)
Found 2475 files belonging to 2 classes.
bellpepper_class_names = bellpepper_dataset.class_names
bellpepper_class_names #Names of folder present in BellPepperPlant
['Pepper__bell___Bacterial_spot', 'Pepper__bell___healthy']
len(bellpepper_dataset)
78
78*32
2496
for image_batch, label_batch in bellpepper_dataset.take(1):
print(image_batch.shape)
print(label_batch.numpy())
#Basically it provides a batch size, image size and RGB channels
#label batch signifies the class number
(32, 256, 256, 3) [0 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 0 0 1 0 0]
plt.figure(figsize=(10, 10))
for image_batch, label_batch in bellpepper_dataset.take(1):
for i in range(9): #here in range max value we can give is 32 bcoz batch size is 32
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image_batch[i].numpy().astype("uint8"))
plt.title(bellpepper_class_names[label_batch[i]])
plt.axis("off")
len(bellpepper_dataset)
78
# 70% -> Training dataset
# 15% -> Validation dataset
# 15% -> Testing dataset
train_size = 0.7
len(bellpepper_dataset)*train_size
54.599999999999994
train_bellpepperdataset = bellpepper_dataset.take(54) # Considering first 54 values
len(train_bellpepperdataset)
54
test_bellpepperdataset = bellpepper_dataset.skip(54) # Considering values after 54
len(test_bellpepperdataset)
24
validation_size = 0.15
len(bellpepper_dataset)*validation_size
11.7
validation_bellpepperdataset = test_bellpepperdataset.take(11)
len(validation_bellpepperdataset)
11
test_bellpepperdataset = test_bellpepperdataset.skip(11)
len(test_bellpepperdataset)
13
train_bellpepperds, validation_bellpepperds, test_bellpepperds = get_dataset_partitions_tf(bellpepper_dataset)
print(len(train_bellpepperds))
print(len(validation_bellpepperds))
print(len(test_bellpepperds))
54 11 13
# Here cache is used to store the image so that we can read the image from the disk which improves the performance.
# Prefetch is used because if GPU is busy with training purpose meanwhile CPU will read the next batch so that the performance is optimized.
train_bellpepperds = train_bellpepperds.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
validation_bellpepperds = validation_bellpepperds.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
test_bellpepperds = test_bellpepperds.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
#Thus we get the optimized Training, Validation and Testing dataset.
#Data preprocessing
resize_and_rescale = tf.keras.Sequential([
layers.experimental.preprocessing.Resizing(imageSize, imageSize), #Supose if the size of image is not 256 then this will take care of that.
layers.experimental.preprocessing.Rescaling(1.0/255) #Rescaling the image to 255 and supply the layer when we actually build our model.
])
#Data augmentation :- Techniques used to increase the amount of data by adding slightly modified copies of already existing data
data_augmentation = tf.keras.Sequential([
layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical"),
layers.experimental.preprocessing.RandomRotation(0.2)
])
#We just created layers for preprocessing and we will this layer in our actual model.
input_shape = (batchSize, imageSize, imageSize, channels)
n_classes = 2
model = models.Sequential([
resize_and_rescale,
layers.Conv2D(32, kernel_size = (3,3), activation='relu', input_shape=input_shape),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(n_classes, activation='softmax'), #softmax function -> normalize the probability of your classes.
])
model.build(input_shape=input_shape)
model.summary()
Model: "sequential_5"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
sequential_3 (Sequential) (32, 256, 256, 3) 0
conv2d_6 (Conv2D) (32, 254, 254, 32) 896
max_pooling2d_6 (MaxPooling (32, 127, 127, 32) 0
2D)
conv2d_7 (Conv2D) (32, 125, 125, 64) 18496
max_pooling2d_7 (MaxPooling (32, 62, 62, 64) 0
2D)
conv2d_8 (Conv2D) (32, 60, 60, 64) 36928
max_pooling2d_8 (MaxPooling (32, 30, 30, 64) 0
2D)
conv2d_9 (Conv2D) (32, 28, 28, 64) 36928
max_pooling2d_9 (MaxPooling (32, 14, 14, 64) 0
2D)
conv2d_10 (Conv2D) (32, 12, 12, 64) 36928
max_pooling2d_10 (MaxPoolin (32, 6, 6, 64) 0
g2D)
conv2d_11 (Conv2D) (32, 4, 4, 64) 36928
max_pooling2d_11 (MaxPoolin (32, 2, 2, 64) 0
g2D)
flatten_1 (Flatten) (32, 256) 0
dense_2 (Dense) (32, 64) 16448
dense_3 (Dense) (32, 2) 130
=================================================================
Total params: 183,682
Trainable params: 183,682
Non-trainable params: 0
_________________________________________________________________
model.compile(
optimizer = 'adam',
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits = False),
metrics = ['accuracy'] #to track the gradient descent/ training process.
)
epochs = 10
results = model.fit(
train_bellpepperds,
batch_size=batchSize,
validation_data=validation_bellpepperds,
verbose=1,
epochs=epochs,
)
Epoch 1/10 54/54 [==============================] - 63s 1s/step - loss: 0.5557 - accuracy: 0.7001 - val_loss: 0.3482 - val_accuracy: 0.8835 Epoch 2/10 54/54 [==============================] - 60s 1s/step - loss: 0.3010 - accuracy: 0.8981 - val_loss: 0.3077 - val_accuracy: 0.8608 Epoch 3/10 54/54 [==============================] - 60s 1s/step - loss: 0.2527 - accuracy: 0.9320 - val_loss: 0.1030 - val_accuracy: 0.9545 Epoch 4/10 54/54 [==============================] - 60s 1s/step - loss: 0.1236 - accuracy: 0.9566 - val_loss: 0.0700 - val_accuracy: 0.9773 Epoch 5/10 54/54 [==============================] - 60s 1s/step - loss: 0.0799 - accuracy: 0.9766 - val_loss: 0.0243 - val_accuracy: 0.9943 Epoch 6/10 54/54 [==============================] - 60s 1s/step - loss: 0.0361 - accuracy: 0.9871 - val_loss: 0.0156 - val_accuracy: 0.9915 Epoch 7/10 54/54 [==============================] - 60s 1s/step - loss: 0.0301 - accuracy: 0.9912 - val_loss: 0.0712 - val_accuracy: 0.9801 Epoch 8/10 54/54 [==============================] - 60s 1s/step - loss: 0.0639 - accuracy: 0.9836 - val_loss: 0.0187 - val_accuracy: 0.9943 Epoch 9/10 54/54 [==============================] - 60s 1s/step - loss: 0.0668 - accuracy: 0.9801 - val_loss: 0.0090 - val_accuracy: 0.9943 Epoch 10/10 54/54 [==============================] - 60s 1s/step - loss: 0.0193 - accuracy: 0.9965 - val_loss: 0.0650 - val_accuracy: 0.9773
scores = model.evaluate(test_bellpepperds)
13/13 [==============================] - 4s 227ms/step - loss: 0.0766 - accuracy: 0.9688
scores #returns loss and accuracy
[0.07658757269382477, 0.96875]
results #history
<keras.callbacks.History at 0x1e13d140a90>
results.params
{'verbose': 1, 'epochs': 10, 'steps': 54}
results.history.keys()
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
accuracy = results.history['accuracy']
val_accuracy = results.history['val_accuracy']
loss = results.history['loss']
val_loss = results.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(range(epochs), accuracy, label='Training Accuracy')
plt.plot(range(epochs), val_accuracy, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(range(epochs), loss, label='Training Loss')
plt.plot(range(epochs), val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
import numpy as np
for images_batch, labels_batch in test_bellpepperds.take(1): # where 1 is the number of batches
#print(images_batch[0]) #Tensor format
#print(images_batch[0].numpy()) #Numpy format
#plt.imshow(images_batch[0].numpy().astype('uint8')) #Displays the actual image
first_image = images_batch[0].numpy().astype('uint8')
first_label = labels_batch[0].numpy()
print("Predicting the first image")
plt.imshow(first_image)
print("Actual class label:",bellpepper_class_names[first_label])
batch_prediction = model.predict(images_batch)
print("Predicted class label:",bellpepper_class_names[np.argmax(batch_prediction[0])])
Predicting the first image Actual class label: Pepper__bell___healthy Predicted class label: Pepper__bell___healthy
#Creating a function for inference
def predict_model(model, img):
img_array = tf.keras.preprocessing.image.img_to_array(images[i].numpy())
img_array = tf.expand_dims(img_array, 0)
predictions = model.predict(img_array)
predicted_class = bellpepper_class_names[np.argmax(predictions[0])]
confidence = round(100 * (np.max(predictions[0])), 2)
return predicted_class, confidence
#Running the inference on few sample images
plt.figure(figsize=(15, 15))
for images, labels in test_bellpepperds.take(1): #Taking 1 batch
for i in range(6): #Considering 9 images at a time
ax = plt.subplot(3, 2, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
predicted_class, confidence = predict_model(model, images[i].numpy())
actual_class = bellpepper_class_names[labels[i]]
plt.title(f"Actual class label: {actual_class},\n Predicted class label: {predicted_class}.\n Confidence: {confidence}%")
plt.axis("off") #Removing the axes
imageSize = 256
batchSize = 32
channels = 3
epochs = 10
#Tomato Plant
tomato_dataset = tf.keras.preprocessing.image_dataset_from_directory(
"tomatoPlant",
shuffle=True,
image_size = (imageSize,imageSize),
batch_size = batchSize
)
Found 16011 files belonging to 10 classes.
class_names_tomato = tomato_dataset.class_names
class_names_tomato #Names of folder present in PotatoPlant
['Tomato_Bacterial_spot', 'Tomato_Early_blight', 'Tomato_Late_blight', 'Tomato_Leaf_Mold', 'Tomato_Septoria_leaf_spot', 'Tomato_Spider_mites_Two_spotted_spider_mite', 'Tomato__Target_Spot', 'Tomato__Tomato_YellowLeaf__Curl_Virus', 'Tomato__Tomato_mosaic_virus', 'Tomato_healthy']
len(tomato_dataset)
501
501*32
16032
for image_batch, label_batch in tomato_dataset.take(1): #Considering 1 batch at a time
print(image_batch.shape)
print(label_batch.numpy())
#Basically it provides a batch size, image size and RGB channels
#label batch signifies the class number
(32, 256, 256, 3) [2 2 3 7 7 7 5 6 4 4 5 5 7 6 0 6 4 0 6 7 3 6 7 7 7 5 7 6 2 2 4 0]
plt.figure(figsize=(10, 10))
for image_batch, label_batch in tomato_dataset.take(1):
for i in range(9): #here in range max value we can give is 32 bcoz batch size is 32
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image_batch[i].numpy().astype("uint8"))
plt.title(class_names_tomato[label_batch[i]])
plt.axis("off")
len(tomato_dataset)
501
# 70% -> Training dataset
# 15% -> Validation dataset
# 15% -> Testing dataset
train_size = 0.7
len(tomato_dataset)*train_size
350.7
train_tomatodataset = tomato_dataset.take(350) # Considering first 350 values
len(train_tomatodataset)
350
test_tomatodataset = tomato_dataset.skip(350) # Considering values after 350
len(test_tomatodataset)
151
validation_size = 0.15
len(tomato_dataset)*validation_size
75.14999999999999
validation_potatodataset = test_tomatodataset.take(75)
len(validation_potatodataset)
75
test_tomatodataset = test_tomatodataset.skip(75)
len(test_tomatodataset)
1
train_tomatods, validation_tomatods, test_tomatods = get_dataset_partitions_tf(tomato_dataset)
print(len(train_tomatods))
print(len(validation_tomatods))
print(len(test_tomatods))
350 75 76
# Here cache is used to store the image so that we can read the image from the disk which improves the performance.
# Prefetch is used because if GPU is busy with training purpose meanwhile CPU will read the next batch so that the performance is optimized.
train_tomatods = train_tomatods.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
validation_tomatods = validation_tomatods.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
test_tomatods = test_tomatods.cache().shuffle(1000).prefetch(buffer_size = tf.data.AUTOTUNE)
#Thus we get the optimized Training, Validation and Testing dataset.
#Data preprocessing
resize_and_rescale = tf.keras.Sequential([
layers.experimental.preprocessing.Resizing(imageSize, imageSize), #Supose if the size of image is not 256 then this will take care of that.
layers.experimental.preprocessing.Rescaling(1.0/255) #Rescaling the image to 255 and supply the layer when we actually build our model.
])
#Data augmentation :- Techniques used to increase the amount of data by adding slightly modified copies of already existing data
data_augmentation = tf.keras.Sequential([
layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical"),
layers.experimental.preprocessing.RandomRotation(0.2)ss
])
#We just created layers for preprocessing and we will this layer in our actual model.
input_shape = (batchSize, imageSize, imageSize, channels)
n_classes = 10
model = models.Sequential([
resize_and_rescale,
layers.Conv2D(32, kernel_size = (3,3), activation='relu', input_shape=input_shape),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, kernel_size = (3,3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(n_classes, activation='softmax'), #softmax function -> normalize the probability of your classes.
])
model.build(input_shape=input_shape)
model.summary()
Model: "sequential_2"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
sequential (Sequential) (32, 256, 256, 3) 0
conv2d (Conv2D) (32, 254, 254, 32) 896
max_pooling2d (MaxPooling2D (32, 127, 127, 32) 0
)
conv2d_1 (Conv2D) (32, 125, 125, 64) 18496
max_pooling2d_1 (MaxPooling (32, 62, 62, 64) 0
2D)
conv2d_2 (Conv2D) (32, 60, 60, 64) 36928
max_pooling2d_2 (MaxPooling (32, 30, 30, 64) 0
2D)
conv2d_3 (Conv2D) (32, 28, 28, 64) 36928
max_pooling2d_3 (MaxPooling (32, 14, 14, 64) 0
2D)
conv2d_4 (Conv2D) (32, 12, 12, 64) 36928
max_pooling2d_4 (MaxPooling (32, 6, 6, 64) 0
2D)
conv2d_5 (Conv2D) (32, 4, 4, 64) 36928
max_pooling2d_5 (MaxPooling (32, 2, 2, 64) 0
2D)
flatten (Flatten) (32, 256) 0
dense (Dense) (32, 64) 16448
dense_1 (Dense) (32, 10) 650
=================================================================
Total params: 184,202
Trainable params: 184,202
Non-trainable params: 0
_________________________________________________________________
model.compile(
optimizer = 'adam',
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits = False),
metrics = ['accuracy'] #to track the gradient descent/ training process.
)
epochs = 10
results_tomato = model.fit(
train_tomatods,
batch_size=batchSize,
validation_data=validation_tomatods,
verbose=1,
epochs=epochs,
)
Epoch 1/10 350/350 [==============================] - 483s 1s/step - loss: 1.5806 - accuracy: 0.4277 - val_loss: 0.9397 - val_accuracy: 0.6700 Epoch 2/10 350/350 [==============================] - 425s 1s/step - loss: 0.8190 - accuracy: 0.7087 - val_loss: 0.5956 - val_accuracy: 0.7967 Epoch 3/10 350/350 [==============================] - 394s 1s/step - loss: 0.5225 - accuracy: 0.8142 - val_loss: 0.5039 - val_accuracy: 0.8204 Epoch 4/10 350/350 [==============================] - 397s 1s/step - loss: 0.4050 - accuracy: 0.8572 - val_loss: 0.3708 - val_accuracy: 0.8683 Epoch 5/10 350/350 [==============================] - 394s 1s/step - loss: 0.3030 - accuracy: 0.8992 - val_loss: 0.2658 - val_accuracy: 0.9100 Epoch 6/10 350/350 [==============================] - 394s 1s/step - loss: 0.2502 - accuracy: 0.9132 - val_loss: 0.2079 - val_accuracy: 0.9296 Epoch 7/10 350/350 [==============================] - 394s 1s/step - loss: 0.2135 - accuracy: 0.9260 - val_loss: 0.2483 - val_accuracy: 0.9167 Epoch 8/10 350/350 [==============================] - 394s 1s/step - loss: 0.1628 - accuracy: 0.9432 - val_loss: 0.2201 - val_accuracy: 0.9217 Epoch 9/10 350/350 [==============================] - 393s 1s/step - loss: 0.1573 - accuracy: 0.9435 - val_loss: 0.1353 - val_accuracy: 0.9521 Epoch 10/10 350/350 [==============================] - 392s 1s/step - loss: 0.1252 - accuracy: 0.9551 - val_loss: 0.1487 - val_accuracy: 0.9504
scores = model.evaluate(test_tomatods)
76/76 [==============================] - 68s 241ms/step - loss: 0.1468 - accuracy: 0.9461
scores #returns loss and accuracy
[0.14679786562919617, 0.9461348652839661]
results_tomato #history
<keras.callbacks.History at 0x227f2cced90>
results_tomato.params
{'verbose': 1, 'epochs': 10, 'steps': 350}
results_tomato.history.keys()
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
accuracy = results_tomato.history['accuracy']
val_accuracy = results_tomato.history['val_accuracy']
loss = results_tomato.history['loss']
val_loss = results_tomato.history['val_loss']
plt.figure(figsize=(8, 8))
plt.subplot(1, 2, 1)
plt.plot(range(epochs), accuracy, label='Training Accuracy')
plt.plot(range(epochs), val_accuracy, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(range(epochs), loss, label='Training Loss')
plt.plot(range(epochs), val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
import numpy as np
for images_batch, labels_batch in test_tomatods.take(1): # where 1 is the number of batches
#print(images_batch[0]) #Tensor format
#print(images_batch[0].numpy()) #Numpy format
#plt.imshow(images_batch[0].numpy().astype('uint8')) #Displays the actual image
first_image = images_batch[0].numpy().astype('uint8')
first_label = labels_batch[0].numpy()
print("Predicting the first image")
plt.imshow(first_image)
print("Actual class label:",class_names_tomato[first_label])
batch_prediction = model.predict(images_batch)
print("Predicted class label:",class_names_tomato[np.argmax(batch_prediction[0])])
Predicting the first image Actual class label: Tomato_Septoria_leaf_spot Predicted class label: Tomato_Septoria_leaf_spot
#Creating a function for inference
def predict_model(model, img):
img_array = tf.keras.preprocessing.image.img_to_array(images[i].numpy())
img_array = tf.expand_dims(img_array, 0)
predictions = model.predict(img_array)
predicted_class = class_names_tomato[np.argmax(predictions[0])]
confidence = round(100 * (np.max(predictions[0])), 2)
return predicted_class, confidence
#Running the inference on few sample images
plt.figure(figsize=(15, 15))
for images, labels in test_tomatodataset.take(1): #Taking 1 batch
for i in range(3): #Considering 9 images at a time
ax = plt.subplot(3, 1, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
predicted_class, confidence = predict_model(model, images[i].numpy())
actual_class = class_names_tomato[labels[i]]
plt.title(f"Actual class label: {actual_class},\n Predicted class label: {predicted_class}.\n Confidence: {confidence}%")
plt.axis("off") #Removing the axes